<!--
  组件职责：该组件只负责组织tab页（tab页下的内容在各自的组件内实现）
  所有tab页下的表单组件实现相同的接口：
    1、通过processNodeForm属性接收完整节点配置的大表单；
    2、在每个表单组件内部数据发生变化时，抛出change事件，事件携带【该组件相关的表单数据】，而不是整个大表单的数据（这样可以直接通过Object.assign的方式将修改的数据合并到大表单上，而不用担心不同tab表单change事件修改数据时相互影响）
-->
<template>
    <div v-show="showPanel" class="property-panel">
        <div v-if="nodeName" class="node-name">
            <!-- 配置节点表单的tab页 -->
            <a-tabs v-if="!showGateway" default-active-key="attribute">
                <a-tab-pane key="attribute" :tab="t('attributeSetting')">
                    <!-- 配置属性设置的表单组件：根据当前选中的节点类型，不同节点类型会对应不同的组件 -->
                    <component
                        :is="elementType === 'bpmn:StartEvent' ? 'startNodeAttributeForm' : 'taskNodeAttributeForm'"
                        :process-type="processType"
                        :application-id="applicationId"
                        :process-node-form="processNodeForm"
                        :fetch-response="fetchResponse"
                        @change="handleFormChange"
                        @selectDataSource="handleSelectDataSource"
                    />
                </a-tab-pane>
                <a-tab-pane key="permission" :tab="t('permissionSetting')">
                    <!-- 配置权限的表单组件 -->
                    <permission-form :process-node-form="processNodeForm" @change="handleFormChange" />
                </a-tab-pane>
                <a-tab-pane
                    v-if="processNodeForm.nodeTaskType === nodeTaskTypeValue.APPROVE"
                    key="approvalButton"
                    :tab="t('approvalButton')"
                >
                    <!-- 配置审批按钮的表单组件 -->
                    <approval-form :process-node-form="processNodeForm" @change="handleFormChange" />
                </a-tab-pane>
            </a-tabs>

            <!-- 配置网关表单的tab页 -->
            <a-tabs v-if="showGateway" default-active-key="gateway">
                <a-tab-pane key="gateway" :tab="t('gatewaySetting')">
                  <!-- 配置审批按钮的表单组件 -->
                  <gateway-node-attribute-form
                      :process-type="processType"
                      :application-id="applicationId"
                      :process-node-form="processNodeForm"
                      :fetch-response="fetchResponse"
                      @change="handleFormChange"
                  />
                </a-tab-pane>
            </a-tabs>
        </div>
    </div>
</template>

<script lang="ts">
    import { defineComponent, ref, computed, watch } from 'vue'
    import { useI18n } from 'vue-i18n'
    import { cloneDeep } from 'lodash-es'
    import { processNodeForm } from '../../types/processNodeForm'
    import { nodeTaskTypeValue } from '@/enums/constant'
    import ApprovalForm from './components/approvalForm.vue'
    import PermissionForm from './components/permissionForm.vue'
    // 开始节点拥有的表单属性
    import startNodeAttributeForm from './components/startNodeAttributeForm.vue'
    // 任务节点拥有的表单属性
    import taskNodeAttributeForm from './components/taskNodeAttributeForm.vue'
    import gatewayNodeAttributeForm from './components/gatewayNodeAttributeForm.vue'

    export default defineComponent({
        name: 'PropertyPanel',
        components: {
            ApprovalForm,
            PermissionForm,
            startNodeAttributeForm,
            taskNodeAttributeForm,
          gatewayNodeAttributeForm
        },
        props: {
            fetchResponse: {
                type: Object,
                default: () => ({})
            },
            processType: {
                type: String,
                default: ''
            },
            applicationId: {
                type: String,
                default: ''
            },
            currentProcessNodeForm: {
                type: Object,
                default: () => ({})
            },
            currentModelerElement: {
                type: Object,
                default: () => ({})
            }
        },
        emits: ['processNodeFormChange', 'selectDataSource'],
        setup(props, { emit }) {
            const { t } = useI18n()

            const changeCount = ref<number>(0)
            // 当前选中的节点元素
            const element = computed(() => {
                return props.currentModelerElement
            })
            // 当前选中节点的类型
            const elementType = computed(() => {
                return element.value?.type
            })
            // 当前选中节点的名称
            const nodeName = computed(() => {
                if (element.value) {
                    const bizObj = element.value.businessObject
                    const type = bizObj?.eventDefinitions ? bizObj.eventDefinitions[0].$type : bizObj?.$type
                    return t(`nodeName.${type}`) || type
                }
                return ''
            })
            // 当前选中节点对应的表单数据
            const processNodeForm = ref<processNodeForm>()

            watch(
                () => props.currentProcessNodeForm,
                () => {
                    processNodeForm.value = cloneDeep(props.currentProcessNodeForm) as processNodeForm
                },
                {
                    immediate: true,
                    deep: true
                }
            )

            // 是否显示属性配置
            const showPanel = computed(() => {
                if (elementType.value) {
                    if (elementType.value === 'bpmn:SequenceFlow') {
                        return element.value.businessObject.sourceRef.$type.indexOf('Gateway') > -1
                    }
                    if (elementType.value === 'bpmn:EndEvent') {
                        return false
                    }
                    // 只有任务才回显示
                    if (elementType.value !== 'bpmn:StartEvent' && elementType.value.indexOf('Task') === -1) {
                        return false
                    }
                }
                return element.value?.id
            })

            // 是否显示网关
            const showGateway = computed(() => {
                if (element.value && elementType.value === 'bpmn:SequenceFlow') {
                    return element.value.businessObject.sourceRef.$type.indexOf('Gateway') > -1
                }
                return false
            })

            // 处理表单数据发生变化的事件
            function handleFormChange(currentFormData) {
                changeCount.value++
                Object.assign(processNodeForm.value, currentFormData)
                // 抛出change事件，携带processNodeForm的数据，由父组件更新节点列表的数据
                emit('processNodeFormChange', cloneDeep(processNodeForm.value))
            }

            // 处理选择数据源的事件
            function handleSelectDataSource(currentDataSource) {
                emit('selectDataSource', currentDataSource)
            }

            // 暴露给组件外，获取属性表单的改变次数
            function getChangeCount(): number {
                return changeCount.value
            }
            // 暴露给组件外，设置属性表单改变次数的方法
            function setChangeCount(count) {
                changeCount.value = count
            }

            return {
                // 组件属性
                nodeName,
                elementType,
                showPanel,
                showGateway,
                processNodeForm,
                nodeTaskTypeValue,

                // 组件方法
                t, // 国际化方法
                handleFormChange,
                handleSelectDataSource,

                // 暴露给组件外的方法
                getChangeCount,
                setChangeCount
            }
        }
    })
</script>

<style lang="less">
    .property-panel {
        height: 100%;
        .@{ant-prefix}-tabs{
          .@{ant-prefix}-tabs-nav-list{
            width: 100%;
            .@{ant-prefix}-tabs-tab{
              width: 100%;
              justify-content: center;
            }
          }
        }
      .collapse-content-box {
            background-color: #fff;
            padding: 15px 20px;

            .option {
                width: 100%;
                color: rgba(0, 0, 0, 0.65);
                display: -webkit-box;
                display: -ms-flexbox;
                display: flex;
                -webkit-box-align: start;
                -ms-flex-align: start;
                align-items: flex-start;
                padding: 0 10px;

                .form-item {
                    margin-bottom: 15px;
                }

                > .title {
                    position: relative;
                    margin-right: 12px;
                    padding-left: 0;
                    line-height: 26px;
                    height: 26px;
                    min-width: 85px;
                    overflow: hidden;
                    text-overflow: ellipsis;
                    white-space: nowrap;
                    text-align: right;

                    &.item-required {
                        &:before {
                            display: inline-block;
                            margin-right: 4px;
                            color: #f5222d;
                            font-size: 14px;
                            font-family: SimSun, sans-serif;
                            line-height: 1;
                            content: '*';
                        }
                    }
                }
            }

            .form-item {
                -webkit-box-flex: 1;
                -ms-flex: 1;
                flex: 1;
                padding: 0 5px;
                min-width: 0;
            }

            .@{ant-prefix}-select,
            .@{ant-prefix}-calendar-picker {
                width: 100%;
            }

            .@{ant-prefix}-radio-wrapper {
                width: 95px;
                overflow: hidden;
                text-overflow: ellipsis;
            }
        }

        .checkbox-style {
            margin-top: 10px;
            margin-left: 1px;

            span {
                margin-left: 0px;
            }
        }

        .base-select-list {
            height: 80px;
            border: 1px solid #e0e0e0;
            margin-bottom: 10px;
            overflow: auto;

            .select-empty {
                cursor: pointer;
                line-height: 78px;
                text-align: center;
                color: #989898;
            }

            .select-item {
                display: inline-block;
                line-height: 30px;
                margin: 5px 0 0 5px;
                padding: 0 10px;
                border-radius: 1px;
                background: #f3f6fc;

                .remove-btn {
                    cursor: pointer;
                    margin-left: 10px;
                    padding: 3px;
                    color: #999;
                }

                .select-icon {
                    font-size: 15px;
                    padding-right: 4px;
                    vertical-align: middle;
                    line-height: 22px;

                    &-user {
                        color: #ed5565;
                    }

                    &-users {
                        color: #248af9;
                    }

                    &-apartment {
                        color: #fa0;
                    }
                }
            }

            &.is-disabled {
                cursor: not-allowed;

                .select-empty {
                    cursor: not-allowed;
                    background-color: #f5f5f5;
                }
            }
        }
    }
</style>

<i18n>
zh-CN:
  nodeName:
    'bpmn:Process': '流程'
    'bpmn:StartEvent': '开始事件'
    'bpmn:IntermediateThrowEvent': '中间事件'
    'bpmn:Task': '任务'
    'bpmn:SendTask': '发送任务'
    'bpmn:ReceiveTask': '接收任务'
    'bpmn:UserTask': '用户任务'
    'bpmn:ManualTask': '手工任务'
    'bpmn:BusinessRuleTask': '业务规则任务'
    'bpmn:ServiceTask': '服务任务'
    'bpmn:ScriptTask': '脚本任务'
    'bpmn:EndEvent': '结束事件'
    'bpmn:SequenceFlow': '流程线'
    'bpmn:ExclusiveGateway': '互斥网关'
    'bpmn:ParallelGateway': '并行网关'
    'bpmn:InclusiveGateway': '相容网关'
    'bpmn:ComplexGateway': '复杂网关'
    'bpmn:EventBasedGateway': '事件网关'
  permissionSetting: '权限设置'
  attributeSetting: '属性设置'
  approvalButton: '审批按钮'
  gatewaySetting: '条件节点连接线'
</i18n>
